package order

import (
	"context"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"git.mycaigou.com/gfyx/common/usermetadata"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/area"
	orderRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/business_opportunity/order"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/opensearch_remote"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/base/profit"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/job_center"
	"git.myscrm.cn/golang/stark/v4"
	"strings"
	"time"
)

type orderService struct {
	orderRepo       orderRepo.GfyxOrderRepoIface
	profitService   profit.ProfitServiceIface
	areaRepo        area.AreaConfigRepositoryIface
	jobService      job_center.JobCenterServiceIface
	openSearchRepos opensearch_remote.OpenSearchRepositoryIface
}

func NewOrderService(
	orderRepo orderRepo.GfyxOrderRepoIface,
	profitService profit.ProfitServiceIface,
	areaRepo area.AreaConfigRepositoryIface,
	jobService job_center.JobCenterServiceIface,
	openSearchRepos opensearch_remote.OpenSearchRepositoryIface,
) OrderServiceIface {
	return &orderService{
		orderRepo:       orderRepo,
		profitService:   profitService,
		areaRepo:        areaRepo,
		jobService:      jobService,
		openSearchRepos: openSearchRepos,
	}
}

func (s *orderService) SaveOrder(ctx context.Context, request *pb.SaveOrderRequest) (int64, bool, error) {
	availableExportNum, err := s.getAvailableExportNum(ctx)
	if err != nil {
		return 0, false, err
	}

	dataTotal, err := s.jobService.GetJobRecordTotal(ctx, request.Type, request.Condition)
	if err != nil {
		return 0, false, err
	}

	if dataTotal == 0 {
		return 0, false, errors.New("可导出数据为空")
	}

	if request.Number > int32(dataTotal) {
		request.Number = int32(dataTotal)
	}

	curUser := usermetadata.GetMetaUserInfo(ctx)
	if request.Id != 0 {
		orderPo, err := s.orderRepo.QueryOrderById(ctx, request.Id)
		if err != nil {
			return 0, false, err
		}
		if orderPo == nil {
			return 0, false, errors.New("订单不存在")
		}
		if orderPo.Status == constants.OrderStatusPaid {
			return 0, false, errors.New("订单已支付")
		}
		if orderPo.Status == constants.OrderStatusCancel {
			return 0, false, errors.New("订单已取消")
		}
		if orderPo.Number > availableExportNum {
			return 0, false, nil
		}
		err = s.orderRepo.UpdateOrderByCondition(ctx,
			map[string]interface{}{"id": request.Id, "is_deleted": constants.IsDeletedFalse},
			map[string]interface{}{"status": constants.OrderStatusPaid,
				"payment_time": time.Now(), "modified_by": curUser.UserId, "modified_on": time.Now()})
		if err != nil {
			return 0, false, err
		}
		//如果支付成功，则创建并启动任务
		_, err = s.jobService.CreateJobAndRun(ctx, orderPo.Id, orderPo.Type, orderPo.Number, constants.JobMethodExport, orderPo.Params)
		if err != nil {
			return 0, false, err
		}
		return request.Id, true, nil
	}
	canPay := false
	if request.Number <= availableExportNum {
		canPay = true
	}
	data := &orderRepo.GfyxOrderPo{
		Type:        request.Type,
		Params:      request.Condition,
		PaymentWay:  constants.PaymentWayEnterprise,
		Digest:      s.getDigest(ctx, request.Type, request.Condition),
		Status:      constants.OrderStatusUnpaid,
		PaymentTime: sql.NullTime{Valid: false},
		Amount:      request.Number * constants.SingleRecordPrice,
		Number:      request.Number,
		Total:       int32(dataTotal),
		Price:       constants.SingleRecordPrice,
		CreatedOn:   time.Now(),
		CreatedBy:   curUser.UserId,
		ModifiedOn:  time.Now(),
		ModifiedBy:  curUser.UserId,
		IsDeleted:   constants.IsDeletedFalse,
	}
	// 当前订单使用的数量小于等于可用条数，则订单直接支付
	if canPay {
		data.Status = constants.OrderStatusPaid
		data.PaymentTime = sql.NullTime{Valid: true, Time: time.Now()}
	}

	orderPo, err := s.orderRepo.SaveOrder(ctx, data)
	if err != nil {
		return 0, false, err
	}

	if canPay {
		//如果支付成功，则创建并启动任务
		_, err := s.jobService.CreateJobAndRun(ctx, orderPo.Id, request.Type, request.Number, constants.JobMethodExport, request.Condition)
		if err != nil {
			return 0, false, err
		}
	}

	return orderPo.Id, canPay, nil
}

func (s *orderService) getDigest(ctx context.Context, reqType int32, condition string) string {
	switch reqType {
	case constants.OrderTypeCustomerExport:
		return s.generateCustomerDigest(ctx, condition)
	case constants.OrderTypeProjectExport:
		return s.generateProjectDigest(ctx, condition)
	case constants.OrderTypeBidExport, constants.OrderTypeCustomerDetailPurchaseExport:
		return s.generateBidDigest(ctx, condition)
	case constants.OrderTypeCustomerDetailLandExport:
		return s.generateCustomerDetailTakeLandDigest(ctx, condition)
	case constants.OrderTypeCustomerDetailBuildExport:
		return s.generateCustomerDetailBuildDigest(ctx, condition)
	case constants.OrderTypeCustomerDetailSaleExport:
		return s.generateCustomerDetailSaleDigest(ctx, condition)
	case constants.OrderTypeCustomerDetailCooperationExport:
		return s.generateCustomerDetailCooperationDigest(ctx, condition)
	case constants.OrderTypeCustomerDetailCaseExport:
		return s.generateCustomerDetailCaseDigest(ctx, condition)
	}
	return ""
}

func (s *orderService) generateCustomerDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.SearchCustomerListRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDigest condition:%s err:%s", condition, err)
		return ""
	}

	var digests []string

	areaCode2Name := make(map[string]string)
	if len(requestDto.AreaCodes) != 0 || len(requestDto.BiddingArea) != 0 {
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
	}

	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}
	companyIdentityDigest := formatArrayDigest("企业属性", requestDto.CompanyIdentity)
	if companyIdentityDigest != "" {
		digests = append(digests, companyIdentityDigest)
	}
	if len(requestDto.AreaCodes) != 0 {
		var areaNames []string
		for _, code := range requestDto.AreaCodes {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("企业地址", areaNames))
		}
	}
	companyLevelDigest := formatArrayDigest("企业等级", requestDto.CompanyLevel)
	if companyLevelDigest != "" {
		digests = append(digests, companyLevelDigest)
	}

	companyLabelDigest := formatArrayDigest("企业标签", requestDto.CompanyLabel)
	if companyLabelDigest != "" {
		digests = append(digests, companyLabelDigest)
	}
	companyTypeDigest := formatArrayDigest("企业类型", requestDto.CompanyType)
	if companyTypeDigest != "" {
		digests = append(digests, companyTypeDigest)
	}

	industryCategoryDigest := formatArrayDigest("所在行业", requestDto.IndustryCategory)
	if industryCategoryDigest != "" {
		digests = append(digests, industryCategoryDigest)
	}

	landUsageLabelDigest := formatArrayDigest("土地用途", requestDto.LandUsageLabel)
	if landUsageLabelDigest != "" {
		digests = append(digests, landUsageLabelDigest)
	}
	projectLabelDigest := formatArrayDigest("工程用途", requestDto.ProjectTypeLabel)
	if projectLabelDigest != "" {
		digests = append(digests, projectLabelDigest)
	}
	fitmentFeeLabelDigest := formatArrayDigest("装修类型", requestDto.FitmentFeeLabel)
	if fitmentFeeLabelDigest != "" {
		digests = append(digests, fitmentFeeLabelDigest)
	}
	creditLevelDigest := formatArrayDigest("信用评级", requestDto.CreditLevel)
	if creditLevelDigest != "" {
		digests = append(digests, creditLevelDigest)
	}
	if len(requestDto.BiddingArea) != 0 {
		var areaNames []string
		for _, code := range requestDto.BiddingArea {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("企业地址", areaNames))
		}
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateProjectDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.SearchProjectRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDigest condition:%s err:%s", condition, err)
		return ""
	}

	var digests []string
	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("甲方单位", details[0].CompanyName))
		}
	}
	areaCode2Name := make(map[string]string)
	if len(requestDto.AreaCode) != 0 || len(requestDto.CompanyAreaCode) != 0 {
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
	}

	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	if len(requestDto.AreaCode) != 0 {
		var areaNames []string
		for _, code := range requestDto.AreaCode {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("项目地区", areaNames))
		}
	}

	landUsageDigest := formatArrayDigest("土地用途", requestDto.LandUsage)
	if landUsageDigest != "" {
		digests = append(digests, landUsageDigest)
	}
	projectTypeDigest := formatArrayDigest("工程用途", requestDto.ProjectType)
	if projectTypeDigest != "" {
		digests = append(digests, projectTypeDigest)
	}
	if requestDto.TakeLandDateStart != "" && requestDto.TakeLandDateEnd != "" {
		digests = append(digests, formatStringDigest("拿地日期", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.TakeLandDateStart, " ")[0], strings.Split(requestDto.TakeLandDateEnd, " ")[0])))
	}

	if requestDto.ProjectDateStart != "" && requestDto.ProjectDateEnd != "" {
		digests = append(digests, formatStringDigest("立项日期", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.ProjectDateStart, " ")[0], strings.Split(requestDto.ProjectDateEnd, " ")[0])))
	}

	if requestDto.BuildingDateStart != "" && requestDto.BuildingDateEnd != "" {
		digests = append(digests, formatStringDigest("开工日期", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.BuildingDateStart, " ")[0], strings.Split(requestDto.BuildingDateEnd, " ")[0])))
	}

	if requestDto.OpenDateStart != "" && requestDto.OpenDateEnd != "" {
		digests = append(digests, formatStringDigest("开盘日期", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.OpenDateStart, " ")[0], strings.Split(requestDto.OpenDateEnd, " ")[0])))
	}
	if requestDto.CompletedDateStart != "" && requestDto.CompletedDateEnd != "" {
		digests = append(digests, formatStringDigest("竣工日期", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.CompletedDateStart, " ")[0], strings.Split(requestDto.CompletedDateEnd, " ")[0])))
	}
	if len(requestDto.CompanyAreaCode) != 0 {
		var areaNames []string
		for _, code := range requestDto.CompanyAreaCode {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("企业地区", areaNames))
		}
	}
	if len(requestDto.CompanyType) != 0 {
		digests = append(digests, formatArrayDigest("企业类型", requestDto.CompanyType))
	}
	if len(requestDto.CompanyLabel) != 0 {
		digests = append(digests, formatArrayDigest("企业标签", requestDto.CompanyLabel))
	}
	if len(requestDto.IndustryCategory) != 0 {
		digests = append(digests, formatArrayDigest("所在行业", requestDto.IndustryCategory))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateBidDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.SearchBidRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailBiddingDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string

	areaCode2Name := make(map[string]string)
	if len(requestDto.AreaCode) != 0 {
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
	}

	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("招标单位", details[0].CompanyName))
		}
	}

	biddingPeriodDigest := formatArrayDigest("招标阶段", requestDto.Type)
	if biddingPeriodDigest != "" {
		digests = append(digests, biddingPeriodDigest)
	}
	if len(requestDto.AreaCode) != 0 {
		var areaNames []string
		for _, code := range requestDto.AreaCode {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("招标地区", areaNames))
		}
	}
	if requestDto.PublishDateStart != "" && requestDto.PublishDateEnd != "" {
		digests = append(digests, formatStringDigest("发布时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.PublishDateStart, " ")[0], strings.Split(requestDto.PublishDateEnd, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateCustomerDetailTakeLandDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.GetTakeLandListRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailTakeLandDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string

	areaCode2Name := make(map[string]string)
	if len(requestDto.AreaCode) != 0 {
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
	}
	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("甲方单位", details[0].CompanyName))
		}
	}

	if len(requestDto.AreaCode) != 0 {
		var areaNames []string
		for _, code := range requestDto.AreaCode {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("项目地区", areaNames))
		}
	}
	landUsageDigest := formatArrayDigest("土地用途", requestDto.LandUsage)
	if landUsageDigest != "" {
		digests = append(digests, landUsageDigest)
	}
	if requestDto.TakeLandDateStart != "" && requestDto.TakeLandDateEnd != "" {
		digests = append(digests, formatStringDigest("拿地时间", fmt.Sprintf("%s至%s", strings.Split(requestDto.TakeLandDateStart, " ")[0], strings.Split(requestDto.TakeLandDateEnd, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateCustomerDetailSaleDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.SaleListRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailSaleDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string

	areaCode2Name := make(map[string]string)
	if len(requestDto.Area) != 0 {
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
	}
	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("甲方单位", details[0].CompanyName))
		}
	}

	if len(requestDto.Area) != 0 {
		var areaNames []string
		for _, code := range requestDto.Area {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("项目地区", areaNames))
		}
	}
	fitmentFeeDigest := formatArrayDigest("装修类型", requestDto.FitmentFeeLabel)
	if fitmentFeeDigest != "" {
		digests = append(digests, fitmentFeeDigest)
	}
	propertyCategoryDigest := formatArrayDigest("项目类型", requestDto.PropertyCategoryLabel)
	if propertyCategoryDigest != "" {
		digests = append(digests, propertyCategoryDigest)
	}
	if requestDto.OpeningTimeStart != "" && requestDto.OpeningTimeEnd != "" {
		digests = append(digests, formatStringDigest("开盘时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.OpeningTimeStart, " ")[0], strings.Split(requestDto.OpeningTimeEnd, " ")[0])))
	}
	if requestDto.DeliveryTimeStart != "" && requestDto.DeliveryTimeEnd != "" {
		digests = append(digests, formatStringDigest("交房时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.DeliveryTimeStart, " ")[0], strings.Split(requestDto.DeliveryTimeEnd, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateCustomerDetailBuildDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.BuildingListRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailBuildDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string

	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("甲方单位", details[0].CompanyName))
		}
	}

	if len(requestDto.Area) != 0 {
		areaCode2Name := make(map[string]string)
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
		var areaNames []string
		for _, code := range requestDto.Area {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("项目地区", areaNames))
		}
	}
	prjTypeDigest := formatArrayDigest("工程用途", requestDto.PrjTypeNum)
	if prjTypeDigest != "" {
		digests = append(digests, prjTypeDigest)
	}
	prjPropertyDigest := formatArrayDigest("建筑性质", requestDto.PrjPropertyNum)
	if prjPropertyDigest != "" {
		digests = append(digests, prjPropertyDigest)
	}
	if requestDto.StartDateStart != "" && requestDto.StartDateEnd != "" {
		digests = append(digests, formatStringDigest("立项/开工时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.StartDateStart, " ")[0], strings.Split(requestDto.StartDateEnd, " ")[0])))
	}
	if requestDto.CompleteDateStart != "" && requestDto.CompleteDateEnd != "" {
		digests = append(digests, formatStringDigest("竣工时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.CompleteDateStart, " ")[0], strings.Split(requestDto.CompleteDateEnd, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateCustomerDetailCooperationDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.ContactListRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailCooperationDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string
	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}

	var cooperationCountArr []string
	for _, cooperationCount := range requestDto.CooperationCount {
		cooperationCountArr = append(cooperationCountArr, fmt.Sprintf("%d-%d", cooperationCount.Min, cooperationCount.Max))
	}
	if len(cooperationCountArr) != 0 {
		digests = append(digests, formatArrayDigest("合作数量", cooperationCountArr))
	}
	if requestDto.CooperationTimeStart != "" && requestDto.CooperationTimeEnd != "" {
		digests = append(digests, formatStringDigest("合作时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.CooperationTimeStart, " ")[0], strings.Split(requestDto.CooperationTimeEnd, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func (s *orderService) generateCustomerDetailCaseDigest(ctx context.Context, condition string) string {
	if condition == "" {
		return ""
	}
	requestDto := pb.GetSupplierProjectRequest{}
	err := json.Unmarshal([]byte(condition), &requestDto)
	if err != nil {
		stark.Logger.Errorf(ctx, "generateCustomerDetailCaseDigest condition:%s err:%s", condition, err)
		return ""
	}
	var digests []string
	keywordDigest := formatStringDigest("关键字", requestDto.Keyword)
	if keywordDigest != "" {
		digests = append(digests, keywordDigest)
	}
	if requestDto.OrganizingCode != "" {
		details, _ := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{
			OrganizingCodes: requestDto.OrganizingCode,
		})
		if len(details) != 0 {
			digests = append(digests, formatStringDigest("合作单位", details[0].CompanyName))
		}
	}
	if len(requestDto.AreaCode) != 0 {
		areaCode2Name := make(map[string]string)
		list, _ := s.areaRepo.AreaConfigList(ctx)
		for _, areaConfigPo := range list {
			areaCode2Name[areaConfigPo.ItemCode] = areaConfigPo.ItemName
		}
		var areaNames []string
		for _, code := range requestDto.AreaCode {
			if areaName, ok := areaCode2Name[code]; ok && areaName != "" {
				areaNames = append(areaNames, areaName)
			}
		}
		if len(areaNames) != 0 {
			digests = append(digests, formatArrayDigest("案例地区", areaNames))
		}
	}
	if requestDto.CoopTimeMin != "" && requestDto.CoopTimeMax != "" {
		digests = append(digests, formatStringDigest("合作时间", fmt.Sprintf("%s至%s",
			strings.Split(requestDto.CoopTimeMin, " ")[0], strings.Split(requestDto.CoopTimeMax, " ")[0])))
	}
	if len(digests) == 0 {
		return ""
	}
	return fmt.Sprintf("%s等%d项筛选项", strings.Join(digests, "，"), len(digests))
}

func formatStringDigest(name string, value string) string {
	if value == "" {
		return ""
	}
	return fmt.Sprintf("%s:{%s}", name, value)
}

func formatArrayDigest(name string, arr []string) string {
	if len(arr) == 0 {
		return ""
	}
	if len(arr) > 5 {
		return fmt.Sprintf("%s:{%s...}", name, strings.Join(arr[:5], "、"))
	}
	return fmt.Sprintf("%s:{%s}", name, strings.Join(arr, "、"))
}

func buildOrderListCondition(request *pb.GetOrderListRequest) map[string]interface{} {
	condition := map[string]interface{}{
		"is_deleted": constants.IsDeletedFalse,
	}

	if request.Keyword != "" {
		condition["keyword"] = request.Keyword
	}
	if len(request.Status) != 0 {
		condition["status"] = request.Status
	}
	if request.PaymentTimeMin != "" {
		condition["payment_time_min"] = request.PaymentTimeMin
	}
	if request.PaymentTimeMax != "" {
		condition["payment_time_max"] = request.PaymentTimeMax
	}
	if len(request.Type) != 0 {
		condition["type"] = request.Type
	}
	if len(request.PaymentWay) != 0 {
		condition["payment_way"] = request.PaymentWay
	}
	return condition
}

func (s *orderService) QueryOrderList(ctx context.Context, request *pb.GetOrderListRequest) (*pb.GetOrderListResponse, error) {
	//懒汉模式，每次访问接口的时候，将超过24小时未支付的订单置为已取消
	_ = s.orderRepo.UpdateOrderByCondition(ctx,
		map[string]interface{}{"status": constants.OrderStatusUnpaid, "is_deleted": constants.IsDeletedFalse, "expired_time": time.Now().Add(-24 * time.Hour)},
		map[string]interface{}{"status": constants.OrderStatusCancel})

	condition := buildOrderListCondition(request)
	total, list, err := s.orderRepo.QueryOrderList(ctx, condition, &utils.PageInfo{
		PageSize: int(request.PageSize),
		Page:     int(request.Page),
	})
	if err != nil {
		return nil, err
	}

	resp := &pb.GetOrderListResponse{Total: int32(total), List: nil}
	for _, item := range list {
		pbDetail := &pb.OrderDetail{
			Id:         item.Id,
			Type:       item.Type,
			Digest:     item.Digest,
			Fields:     constants.GetOrderTypeFields(item.Type),
			Status:     item.Status,
			Price:      item.Price,
			Number:     item.Number,
			Amount:     item.Amount,
			PaymentWay: item.PaymentWay,
			CreatedBy:  item.CreatedBy,
			CreatedOn:  item.CreatedOn.Format("2006-01-02 15:04:05"),
			ModifiedBy: item.ModifiedBy,
			ModifiedOn: item.ModifiedOn.Format("2006-01-02 15:04:05"),
		}

		if item.PaymentTime.Valid == true {
			pbDetail.PaymentTime = item.PaymentTime.Time.Format("2006-01-02 15:04:05")
		}
		resp.List = append(resp.List, pbDetail)
	}
	return resp, nil
}

func (s *orderService) PreviewOrder(ctx context.Context, request *pb.PreviewOrderRequest) (*pb.PreviewOrderResponse, error) {
	availableExportNum, err := s.getAvailableExportNum(ctx)
	if err != nil {
		return nil, err
	}

	total, err := s.jobService.GetJobRecordTotal(ctx, request.Type, request.Condition)
	if err != nil {
		return nil, err
	}

	resp := &pb.PreviewOrderResponse{
		Type:         request.Type,
		Fields:       constants.GetOrderTypeFields(request.Type),
		Digest:       s.getDigest(ctx, request.Type, request.Condition),
		Price:        constants.SingleRecordPrice,
		Total:        int32(total),
		UnusedNumber: availableExportNum,
	}
	return resp, nil
}

func (s *orderService) getAvailableExportNum(ctx context.Context) (int32, error) {
	exportTotal, startTime, _, err := s.profitService.CalculateTenantProfitExportNum(ctx)
	if err != nil {
		return 0, err
	}
	//2.查询已使用的导出记录数
	usedExportNum, err := s.orderRepo.GetUsedExportNumByTime(ctx, startTime)
	if err != nil {
		return 0, err
	}
	if exportTotal-usedExportNum < 0 {
		return 0, nil
	}
	return exportTotal - usedExportNum, nil
}

func (s *orderService) OrderDetail(ctx context.Context, request *pb.GetOrderDetailRequest) (*pb.GetOrderDetailResponse, error) {
	orderPo, err := s.orderRepo.QueryOrderById(ctx, request.Id)
	if err != nil {
		return nil, err
	}
	if orderPo == nil {
		return nil, errors.New("订单不存在")
	}
	availableExportNum, err := s.getAvailableExportNum(ctx)
	if err != nil {
		return nil, err
	}

	resp := &pb.GetOrderDetailResponse{Order: &pb.OrderDetail{
		Id:           orderPo.Id,
		Type:         orderPo.Type,
		Digest:       orderPo.Digest,
		Fields:       constants.GetOrderTypeFields(orderPo.Type),
		Status:       orderPo.Status,
		Price:        orderPo.Price,
		Number:       orderPo.Number,
		Amount:       orderPo.Amount,
		PaymentWay:   orderPo.PaymentWay,
		CreatedBy:    orderPo.CreatedBy,
		CreatedOn:    orderPo.CreatedOn.Format("2006-01-02 15:04:05"),
		ModifiedBy:   orderPo.ModifiedBy,
		ModifiedOn:   orderPo.ModifiedOn.Format("2006-01-02 15:04:05"),
		UnusedNumber: availableExportNum,
		Total:        orderPo.Total,
	}}
	if orderPo.Status == constants.OrderStatusUnpaid {
		resp.Order.ExpiredOn = orderPo.CreatedOn.AddDate(0, 0, 1).Format("2006-01-02 15:04:05")
	} else if orderPo.Status == constants.OrderStatusPaid {
		resp.Order.JobId, resp.Order.FinishStatus, resp.Order.ResultFileUrl, err = s.jobService.GetJobInfoByOrderId(ctx, request.Id)
		if err != nil {
			fmt.Println("GetJobInfoByOrderId orderId:", request.Id, ",err:", err.Error())
		}
	}
	if orderPo.PaymentTime.Valid == true {
		resp.Order.PaymentTime = orderPo.PaymentTime.Time.Format("2006-01-02 15:04:05")
	}
	return resp, nil
}
